// // Copyright (c) 2009 All Right Reserved // // Stephen Toub // stoub@microsoft.com // 2009-01-01 // Contains ... namespace LargoCommon.Midi { using Abstract; using JetBrains.Annotations; using Music; using System; using System.Globalization; using System.IO; using System.Text; /// A tempo meta event message. [Serializable] public sealed class MetaTempo : MetaEvent { /// /// Tempo Base Number. /// public const int MidiTempoBaseNumber = 60000000; /// /// Max Tempo Value. /// private const int MidiMaxTempoValue = 0xFFFFFF; #region Fields /// The meta id for this event. private const byte EventMetaId = 0x51; /// The tempo for the event. private int tempoValue; #endregion #region Constructors /// Initializes a new instance of the MetaTempo class. /// The amount of time before this event. /// The tempo for the event. public MetaTempo(long deltaTime, int value) : base(deltaTime, EventMetaId) { this.Value = value; } #endregion #region Properties /// Gets or sets the tempo for the event. /// General musical property. public int Tempo { get { if (this.Value != 0) { return (int)Math.Round(1.000f * MidiTempoBaseNumber / this.Value, 0); } return 0; } [UsedImplicitly] set => this.tempoValue = value > 0 ? MidiTempoBaseNumber / value : (int)MusicalTempo.Tempo120; } /// Gets or sets the tempo for the event. /// General musical property. private int Value { get => this.tempoValue; set { if (value < 0 || value > MidiMaxTempoValue) { throw new ArgumentOutOfRangeException(nameof(value), value, "The tempo must be in the range from 0x0 to 0xFFFFFF."); } this.tempoValue = value; } } #endregion #region To String /// Generate a string representation of the event. /// A string representation of the event. public override string ToString() { var sb = new StringBuilder(); sb.Append(base.ToString()); sb.Append("\t"); sb.Append(" Tempo=" + this.Tempo.ToString(CultureInfo.CurrentCulture.NumberFormat)); return sb.ToString(); } #endregion #region Methods /// Write the event to the output stream. /// The stream to which the event should be written. public override void Write(Stream outputStream) { if (outputStream == null) { return; } //// Write out the base event information base.Write(outputStream); //// Event data outputStream.WriteByte(0x03); outputStream.WriteByte((byte)((this.tempoValue & DefaultValue.MaskByte2Of4) >> 16)); //// 0xFF0000 outputStream.WriteByte((byte)((this.tempoValue & DefaultValue.MaskByte3Of4) >> 8)); //// 0x00FF00 outputStream.WriteByte((byte)(this.tempoValue & DefaultValue.MaskByte4Of4)); //// 0x0000FF } #endregion } }